package com.lqwu.mallchatserver.user.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.lqwu.mallchatserver.common.constant.RedisKey;
import com.lqwu.mallchatserver.common.utils.JwtUtils;
import com.lqwu.mallchatserver.common.utils.RedisUtils;
import com.lqwu.mallchatserver.user.service.LoginService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    public static final int TOKEN_EXPIRE_DAYS = 3;
    @Resource
    private JwtUtils  jwtUtils;

    /**
     * 登录,获取登录token
     * @param uid
     * @return
     */
    @Override
    public String login(Long uid) {
        // 1.生成token
        String token = jwtUtils.createToken(uid);
        // 2.保存token到redis中,过期时间3天
        Boolean set = RedisUtils.set(RedisKey.getKey(RedisKey.LOGIN_USER_TOKEN, uid), token, TOKEN_EXPIRE_DAYS, TimeUnit.DAYS);
        return token;
    }

    /**
     * 如果token有效，返回uid
     * @param token
     * @return
     */
    @Override
    public Long getValidUid(String token) {
        // 1.解析token，获取uid
        Long uid = jwtUtils.getUidOrNull(token);
        if (ObjUtil.isNull(uid)){
            return null;
        }
        // 2.判断uid是否在redis中,是否已过期
        String oldToken = RedisUtils.getStr(RedisKey.getKey(RedisKey.getKey(RedisKey.LOGIN_USER_TOKEN, uid)));
        if (ObjUtil.isNull(oldToken)){
            return null;
        }
        // 3.判断token是否一致,一致则返回uid
        return ObjUtil.equals(oldToken, token) ? uid : null;
    }

    /**
     * 刷新token有效期
     * @param token
     */
    @Override
    @Async
    public void renewalTokenIfNecessary(String token) {
        // 1.解析token，获取uid
        Long uid = getValidUid(token);
        // 2.拼接key
        String key = RedisKey.getKey(RedisKey.LOGIN_USER_TOKEN, uid);
        // 3.获取token的剩余生命
        Long remainTime = RedisUtils.getExpire(key);
        // 不存在或已过期
        if (remainTime == -2){
            return;
        }
        // 4.如果剩余生命小于1天，则刷新有效期
        if (remainTime < 1){
            RedisUtils.expire(key, TOKEN_EXPIRE_DAYS, TimeUnit.DAYS);
        }
    }
}
